package com.hnucm.chapter2.a;

import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 代表远程服务端
 */
public class BookManagerService extends Service {
    private static final String TAG="BMS";
    //AIDL方法在服务端的Binder线程池中执行
    //CopyOnWriteArrayList支持并发读写
    //为什么支持CopyOnWriteArrayList，它并不是List的子类
    private CopyOnWriteArrayList<Book> mBookList=new CopyOnWriteArrayList<Book>();
    private CopyOnWriteArrayList<IOnNewBookArrivedListener> mListenerList=new CopyOnWriteArrayList<IOnNewBookArrivedListener>();

    private AtomicBoolean mIsServiceDestoryed = new AtomicBoolean(false);

    public BookManagerService() {
    }

    private Binder mBinder = new IBookManager.Stub() {
        @Override
        public List<Book> getBookList() throws RemoteException {
            return mBookList;
        }

        @Override
        public void addBook(Book book) throws RemoteException {
            mBookList.add(book);
        }

        @Override
        public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
            if(!mListenerList.contains(listener)){
                mListenerList.add(listener);
            }else{
                Log.d(TAG, "registerListener: already exist");
            }
            Log.d(TAG, "registerListener, size:"+mListenerList.size());
        }

        @Override
        public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
            if(mListenerList.contains(listener)){
                mListenerList.remove(listener);
                Log.d(TAG, "unregister listener succeed!");
            }else{
                Log.d(TAG, "no fund,cant unregister. ");
            }
            Log.d(TAG, "unregisterListener, current size:"+mListenerList.size());
        }

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        //page90 权限验证的第二种方法
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                throws RemoteException {
            //采用permission验证
            int check = checkCallingOrSelfPermission("com.ryg.chapter_2.permission.ACCESS_BOOK_SERVICE");
            Log.d(TAG, "check=" + check);
            if (check == PackageManager.PERMISSION_DENIED) {
                return false;
            }

            String packageName = null;
            //getCallingUid()方法获取到包名
            String[] packages = getPackageManager().getPackagesForUid(
                    getCallingUid());
            if (packages != null && packages.length > 0) {
                packageName = packages[0];
            }
            Log.d(TAG, "onTransact: " + packageName);
            if (!packageName.startsWith("com.hnucm")) {
                return false;
            }

            return super.onTransact(code, data, reply, flags);
        }

    };

    @Override
    public void onCreate() {
        super.onCreate();
        //初始化，添加两本书籍信息
        mBookList.add(new Book(1,"Android"));
        mBookList.add(new Book(2,"IOS"));
        new Thread(new ServiceWorker()).start();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mBinder;
    }


    //新线程，每隔5秒添加一本书【
    private class ServiceWorker implements Runnable {
        @Override
        public void run() {
// do background processing here.....
            while (!mIsServiceDestoryed.get()) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int bookId = mBookList.size() + 1;
                Book newBook = new Book(bookId, "new book#" + bookId);
                try {
                    onNewBookArrived(newBook);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void onNewBookArrived(Book book) throws RemoteException{
        mBookList.add(book);
        Log.d(TAG, "onNewBookArrived: notify listeners:"+mListenerList.size());
        for (int i = 0; i < mListenerList.size(); i++) {
            IOnNewBookArrivedListener listener = mListenerList.get(i);
            Log.d(TAG, "onNewBookArrived: notify listeners:"+listener);
            listener.onNewBookArrived(book);
        }
    }


}